feat: codecov override with merge squash hash#2371
Conversation
WalkthroughAdds two composite GitHub Actions for Codecov uploads, three Bash helper scripts to locate and download PR/merge-run artifacts, updates CI workflows to use the new actions/scripts (including a post-merge aggregation workflow), and adds a project.default block to codecov.yaml for coverage settings. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2371 +/- ##
=======================================
Coverage ? 46.62%
=======================================
Files ? 340
Lines ? 34302
Branches ? 251
=======================================
Hits ? 15992
Misses ? 17055
Partials ? 1255 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
.github/actions/codecov-merge-upload/action.yml(1 hunks).github/actions/codecov-upload-pr/action.yml(1 hunks).github/scripts/find-codecov-artifact.sh(1 hunks).github/workflows/cli-ci.yaml(5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build_test
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (go)
🔇 Additional comments (9)
.github/actions/codecov-upload-pr/action.yml (2)
23-29: Confirm intent of artifact overwrite.Line 26 enables
overwrite: truefor artifact uploads. Verify this is intentional—successive uploads within the same workflow run will replace prior artifacts. If multiple coverage files are uploaded during a single PR workflow run, this could cause data loss.
1-35: Action structure and inputs are well-defined.The composite action correctly parameterizes artifact metadata, coverage paths, and credentials. The two-step flow (upload artifact, then upload to Codecov) aligns with the PR's intent to preserve coverage data across merge events.
.github/scripts/find-codecov-artifact.sh (1)
26-26: Verify API pagination is sufficient for high-activity repositories.The script limits results to 500 runs per page (
per_page=500). In repositories with frequent PR cycles, this may skip older runs or miss the intended run. Consider implementing pagination or increasing the limit if needed.Also applies to: 33-44, 62-64
.github/workflows/cli-ci.yaml (4)
4-4: Guard conditions correctly prevent redundant builds on PR close.The added
types: [opened, reopened, synchronize, closed]andif: github.event.action != 'closed'guards ensure that build and test jobs only run on PR lifecycle events (not on close), reserving the close event for post-merge Codecov upload. This avoids wasteful CI runs.Also applies to: 24-24, 70-70, 100-100, 119-119
59-67: Coverage upload refactored to use new composite action.The migration from
codecov/codecov-action@v5to./.github/actions/codecov-upload-pris appropriate. Multi-file coverage input is cleaner than concatenation. Verify thatcli/coverage/clover.xmlandcli/coverage/coverage-final.jsonare always generated by the build step; missing files will cause the artifact upload to fail.
116-126: Clarify intent ofalways()in build_test job.The
build_testjob usesalways()in its condition alongside a check for failed results. This ensures the job runs even if upstream jobs fail, but only to report the status. Confirm this is intentional (i.e., you want to propagate failures from upstream jobs as a final status check, not skip CI on partial failure).
128-151: Post-merge job structure is sound.The new
post-mergejob correctly:
- Runs only when a PR is closed and merged (
github.event.action == 'closed' && github.event.pull_request.merged == true).- Checks out the merge commit SHA.
- Invokes the
codecov-merge-uploadaction to fetch coverage artifacts from the PR run and upload to Codecov with the merge commit SHA override.This enables Codecov to attribute coverage to the squash-merged commit on main.
.github/actions/codecov-merge-upload/action.yml (2)
28-38: Action assumes pull_request event context.The
find-runstep references${{ github.event.pull_request.head.sha }}on line 34, which is only available in pull_request events. While the calling workflow (cli-ci.yaml line 128–144) ensures this runs in a pull_request context, the action itself does not validate this assumption.If this action is reused in a non-PR context in the future, it will silently fail (passing an empty string). Consider adding a guard or validation within the action.
1-52: Composite action properly orchestrates artifact discovery and upload.The three-step flow (find run, download artifact, upload to Codecov) correctly chains outputs from the helper script to downstream actions. The use of
run-idandartifact_idfrom the find-run step ensures the correct coverage artifact is downloaded and uploaded with the merge commit SHA override.
Router-nonroot image scan passed✅ No security vulnerabilities found in image: |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
.github/actions/codecov-merge-upload/action.yml (2)
28-38: Add error handling and validation to the find-run step.The
find-runstep (lines 28–38) invokes an external script with no explicit error handling. If the script fails orrun_idis not output, the subsequentdownload-artifactstep will fail with a cryptic error. Consider adding||exit checks or validating outputs in this step for better diagnostics.# After the run command, add a validation check: - name: Find latest successful PR run for this commit id: find-run shell: bash env: GITHUB_TOKEN: ${{ inputs.github-token }} REPO: ${{ github.repository }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} CURRENT_RUN_ID: ${{ github.run_id }} ARTIFACT_NAME: ${{ inputs.artifact-name }} WORKFLOW_PATH: ${{ inputs.workflow-path }} run: | ./.github/scripts/find-codecov-artifact.sh if [ -z "${{ steps.find-run.outputs.run_id }}" ]; then echo "::error::Failed to find codecov artifact run_id" exit 1 fi
48-53: Consider makingoverride_branchconfigurable.The
override_branchis hardcoded to"main"(line 53). If the repository uses alternative default branches or needs flexibility for future changes, this hard-coded value limits reusability. Consider adding an optional input foroverride-branchwith a default of"main".Add an input to the action:
override-branch: description: 'Branch to override in Codecov' required: false default: 'main'Then update the Codecov upload step:
- name: Upload results to Codecov uses: codecov/codecov-action@v5 with: token: ${{ inputs.codecov-token }} override_commit: ${{ inputs.override-commit }} override_branch: ${{ inputs.override-branch }}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.github/actions/codecov-merge-upload/action.yml(1 hunks)codecov.yaml(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
- GitHub Check: build_bun_matrix (bun-darwin-x64)
- GitHub Check: build_bun_matrix (bun-darwin-arm64)
- GitHub Check: build_bun_matrix (bun-windows-x64)
- GitHub Check: build_bun_matrix (bun-linux-arm64)
- GitHub Check: build_bun_matrix (bun-linux-x64)
- GitHub Check: build_test_node_matrix (20.x)
- GitHub Check: build_test_node_matrix (22.x)
- GitHub Check: build_test_default
- GitHub Check: build-cli
- GitHub Check: Analyze (go)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (go)
🔇 Additional comments (4)
.github/actions/codecov-merge-upload/action.yml (3)
28-38: Verify thatgithub.event.pull_request.head.shaexists in the workflow context.This action assumes
github.event.pull_request.head.sha(line 34) is available, which only exists inpull_request-triggered workflows. If this action is used inworkflow_run, post-close, or other event contexts (as suggested by the PR's post-merge upload goal), this variable will be empty/null and artifact lookup will fail. Confirm the action is only invoked in contexts where the pull_request event payload is available, or provide a fallback.
1-54: The helper script exists and is correctly implemented.The
find-codecov-artifact.shscript is present and properly handles all the concerns raised:
Script exists: Confirmed at
./.github/scripts/find-codecov-artifact.shOutput variable: Correctly sets
run_idto$GITHUB_OUTPUT(line 87), which the action consumes as${{ steps.find-run.outputs.run_id }}(line 45 of action.yml)GitHub API parsing: Uses
jqto parse API responses with proper null/empty checks (lines 38-49, 70-76)Edge case handling:
- No artifact found: Exits with error and debug output (lines 78-83)
- Multiple runs: Sorts by
created_atand selectslast(most recent) (lines 46, 73)- Current run exclusion: Filters out the current run with
.id != ($cur|tonumber)(line 41)- Expired artifacts: Explicitly filters with
and .expired == false(line 72)- API failures: Proper curl error handling (lines 32-35, 64)
- Parsing failures: jq error handling (lines 51-54)
Input validation: All required environment variables validated upfront (lines 17-21)
The script is production-ready with comprehensive error handling and proper output conventions for GitHub Actions.
49-49:codecov/codecov-action@v5is current and actively maintained.The latest release is v5.5.1 (Sept 4, 2025), with no v6 or newer versions published. The repository and official Marketplace recommend using @v5, making the major version pin appropriate for this use case.
codecov.yaml (1)
8-12: Configuration is valid and follows Codecov's documented schema.The
project.defaultsection (lines 8-12) correctly mirrors thepatch.defaultsettings and is properly structured undercoverage.status.project. This configuration approach is officially supported by Codecov for post-merge coverage tracking. Theoverride_commitparameter is a separate CI/upload configuration (not part of the YAML), used to associate coverage uploads with specific commits. The identical targets (90%), thresholds (5%), andinformational: trueflags for both patch and project levels are intentional and valid—ensuring consistent coverage requirements across both PR checks and merged code.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
.github/actions/codecov-upload-pr/action.yml (1)
27-27: Consider simplifying artifact naming to avoid redundancy.The artifact name pattern
codecov-pr-build-${{ inputs.artifact-name }}combined with the default input value ofpr-buildproducescodecov-pr-build-pr-build, which is redundant.Since the AI summary mentions this action is used for "artifact lookup and cross-PR artifact usage," consider clarifying the naming scheme. You might simplify to just
${{ inputs.artifact-name }}or use a more descriptive prefix likecodecov-coverage-${{ inputs.artifact-name }}:- name: codecov-pr-build-${{ inputs.artifact-name }} + name: codecov-coverage-${{ inputs.artifact-name }}Alternatively, if the prefix is essential for artifact discovery in downstream workflows, consider renaming the default input value to avoid the redundancy.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.github/actions/codecov-upload-pr/action.yml(1 hunks).github/workflows/router-ci.yaml(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- .github/workflows/router-ci.yaml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: build-router
- GitHub Check: build_push_image (nonroot)
- GitHub Check: build_push_image
- GitHub Check: integration_test (./telemetry)
- GitHub Check: build_test
- GitHub Check: integration_test (./events)
- GitHub Check: image_scan
- GitHub Check: image_scan (nonroot)
- GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (go)
🔇 Additional comments (1)
.github/actions/codecov-upload-pr/action.yml (1)
20-35: Overall structure looks good for PR coverage uploads.The composite action correctly orchestrates artifact upload and Codecov submission. The configuration is straightforward and appropriate for the PR phase of the pipeline.
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
.github/scripts/find-pr-commit.sh (1)
57-87: Add validation for empty/null jq output after commit search.When iterating commits (line 58–77), if jq fails or returns malformed data, the script continues silently. Add a safety check after line 75 to ensure
last_pr_commitis non-empty before breaking, and validate the commit SHA format if needed.Consider adding a basic check:
if [ -z "$commit_sha" ]; then echo "Warning: Empty commit SHA in list, skipping..." >&2 continue fi
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
.github/actions/codecov-merge-upload/action.yml(1 hunks).github/actions/codecov-upload-pr/action.yml(1 hunks).github/scripts/find-codecov-artifact.sh(1 hunks).github/scripts/find-pr-commit.sh(1 hunks).github/workflows/cli-ci.yaml(4 hunks).github/workflows/codecov-post-merge.yaml(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- .github/workflows/cli-ci.yaml
- .github/actions/codecov-upload-pr/action.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: build-router
- GitHub Check: build_push_image
- GitHub Check: build_test
- GitHub Check: integration_test (./telemetry)
- GitHub Check: image_scan
- GitHub Check: integration_test (./events)
- GitHub Check: image_scan (nonroot)
- GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
- GitHub Check: build_push_image (nonroot)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (go)
🔇 Additional comments (3)
.github/workflows/codecov-post-merge.yaml (1)
1-41: Workflow structure and logic look sound.The post-merge workflow correctly chains together PR commit discovery and conditional artifact upload. The skip logic appropriately guards against uploading when no PR commit is found. Inputs to the composite action are clearly specified and properly passed.
.github/scripts/find-pr-commit.sh (1)
17-41: Error handling for PR detection is well-implemented.Both curl calls use the
-sfflag to fail fast on HTTP errors, and exit codes are checked. The PR count validation and retry loop for finding commits are solid. The outputs are correctly formatted for GitHub Actions..github/actions/codecov-merge-upload/action.yml (1)
73-79: Parameter names are correct — no issues found.The codecov-action@v5 officially supports both
override_commitandoverride_branchas valid input parameters. These correspond to Codecov CLI's commit/branch override options and are correctly named in the action configuration.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
.github/scripts/find-codecov-artifact.sh (1)
259-262: Minor: Avoid redundant jq operations for the same sort.Lines 259 and 262 both execute
jq -c 'sort_by(.created_at)'on the same$all_artifactsdata—once for stdout visibility and once for the GITHUB_OUTPUT variable. This is unnecessary. Consider assigning once to a variable and reusing it.# Store the sorted result once artifacts_output=$(echo "$all_artifacts" | jq -c 'sort_by(.created_at)') jq_exit_status=$? # ... validation checks (lines 266–288) ... # Use the same variable for both outputs echo "$artifacts_output" # Line 259 equivalent echo "artifacts_json=$artifacts_output" >> "$GITHUB_OUTPUT" echo "has_artifacts=true" >> "$GITHUB_OUTPUT"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.github/actions/codecov-merge-upload/action.yml(1 hunks).github/scripts/find-codecov-artifact.sh(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- .github/actions/codecov-merge-upload/action.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: build_push_image (nonroot)
- GitHub Check: build_push_image
- GitHub Check: image_scan (nonroot)
- GitHub Check: image_scan
- GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
- GitHub Check: build_test
- GitHub Check: integration_test (./telemetry)
- GitHub Check: integration_test (./events)
- GitHub Check: build-router
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (go)
🔇 Additional comments (1)
.github/scripts/find-codecov-artifact.sh (1)
1-292: Comprehensive error handling and retry logic—solid implementation.The script properly addresses all prior review feedback: curl uses
-sfflags, jq exit statuses are explicitly captured throughout, JSON validation is thorough, and error messages include helpful context. The retry logic with exponential backoff for the initial PR lookup is well-structured, and guard checks prevent empty/null values from propagating.
Right now codecov cannot figure out codecoverage for the main branch because we upload the codecoverage mapped to the commits in the PR, which do not exist as we do a squash merge.
This PR is a workaround for this, so that when the PR is merged we will upload to codecov with the squash merge hash.
Summary by CodeRabbit
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.
Checklist